package de.recipeminer.ui.commands;


import com.google.common.base.Joiner;
import de.recipeminer.tools.LimitablePrintStream;
import de.recipeminer.ui.ConsoleInterface;
import de.recipeminer.ui.parsing.OptionParser;
import joptsimple.OptionSet;
import org.apache.log4j.Logger;

import java.io.PrintWriter;

/**
 * Abstract representation of user request to the application
 *
 * @autor: Markus Ackermann
 */
public abstract class UserCommand {
    private static Logger logger = Logger.getLogger(UserCommand.class);
    protected PrintWriter outputSink;
    protected boolean limitConsoleOutput;
    protected int printedLines;
    private OptionParser specificParser;

    private static final String COMMAND_OPTIONS_INTRO_PATTERN = "Options for %s:";
    
    public abstract boolean run(OptionSet options, LimitablePrintStream out);

    public abstract String commandName();
    
    public abstract void extendOptions(OptionParser parser);

    public String specificHelpString() {
        String optionTerm = String.format("[%s OPTIONS]", commandName().toUpperCase());
        String usageLine = String.format(ConsoleInterface.USAGE_LINE_TEMPLATE, commandName(), optionTerm);
        String optsIntro = String.format(COMMAND_OPTIONS_INTRO_PATTERN, commandName());
        return Joiner.on('\n').join(usageLine, "", optsIntro, specificOptionDescription());
    }
    
    protected String specificOptionDescription () {
        OptionParser parser = specificOptionParser();
        return parser.getHelpText();
    }
    
    public OptionParser specificOptionParser() {
        if(specificParser == null) {
            specificParser = new OptionParser();
            extendOptions(specificParser);
        }
        return specificParser;
    }
    
    
    
    
    
    public static class CommandExecutionException extends RuntimeException {
        public CommandExecutionException(String message) {
            super(message);
        }

        public CommandExecutionException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    
    
    
    public static abstract class WorkflowCommand extends UserCommand {
    }

    public static abstract class ListingCommand extends UserCommand {
    }
}
